home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 6 code / Threads / Threads Package 2.0d17 / Threads.h < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-10  |  8.0 KB  |  246 lines  |  [TEXT/MPS ]

  1. #ifndef __THREADS__
  2. #define __THREADS__
  3.  
  4. /*
  5. // by undefining inline, this C++ source can be compiled with no modifications
  6. // well...maybe
  7. */
  8. #define inline
  9.  
  10. /*  Copyright © 1989-91 by Apple Computer, Inc.  All rights reserved.    */
  11.  
  12. #ifndef Types_h
  13. #include <Types.h>
  14. #endif
  15.  
  16. #define kDefaultStackSize  1024
  17.  
  18. #define kUsesFPU                    1
  19. #define kMainThreadHasPriority        2
  20. #define kDreamEveryTick                4
  21.  
  22. /* Thread errors: */
  23.  
  24. #define threadsNotInitedErr        -2700
  25. #define badThreadErr            -2701
  26. #define threadsNotAvailableErr    -2702
  27. #define wrongThreadsVersErr        -2702
  28. #define badSemaphoreErr            -2703
  29. #define threadQueueNotEmptyErr    -2704
  30. #define badSwapSelectorErr        -2705
  31. #define noOtherThreadsToRunErr    -2706
  32. #define kSemaphoreNotFoundErr    -2712
  33.  
  34. /* Customizable swapping behavior instalation selectors: */
  35.  
  36. #define kCopyContextSel            'cctx'
  37. #define kSwapInSel                'swpi'
  38. #define kSwapOutSel                'swpo'
  39. #define kFreeThreadSel            'tfre'
  40. #define kScheduleSel            'schd'
  41. #define kPreYieldSel            'prey'
  42. #define kPostYieldSel            'post'
  43.  
  44. /* Each thing can be a member of a list, and can also contain a list of other things. */
  45.  
  46. typedef struct Thing**            ThingHandle;
  47. typedef struct Thing*            ThingPtr;
  48.  
  49. struct Thing 
  50.     {
  51.     ThingHandle        fQueue;                /* the containing “Thing list” this thing is on */
  52.     ThingHandle        fNext;                /* the next thing in the list relative to this thing */
  53.     ThingHandle        fPrev;                /* the previous thing in the list relative to this thing */
  54.     ThingHandle        fHead;                /* the first thing in the list of things owned by this thing */
  55.     ThingHandle        fTail;                /* the last thing in the list of things owned by this thing */
  56.     };
  57.  
  58.  
  59.  
  60.  
  61.  
  62. typedef struct Thread**            ThreadHandle;
  63. typedef struct ThreadQueue**    ThreadQueueHandle;
  64. typedef struct Semaphore**        SemaphoreHandle;
  65. typedef struct Thread*            ThreadPtr;
  66. typedef struct ThreadQueue*        ThreadQueuePtr;
  67.  
  68. /*
  69. //    Think C does not handle Pascal procedures very well.
  70. //    The CallPascal() function must be used.
  71. */
  72. #ifdef THINK_C
  73.     typedef OSErr (*ThreadProc)(ThreadHandle);
  74.     typedef void (*SpawnProc)(ThreadHandle,long);
  75.     typedef ThreadHandle (*ScheduleProc)(ThreadHandle);
  76.     typedef Boolean (*ThreadIterProc)(ThreadHandle, void*);
  77.     typedef Boolean             (*ThingIterProc)(ThingHandle, void*);
  78. #else
  79.     typedef pascal OSErr (*ThreadProc)(ThreadHandle);
  80.     typedef pascal void (*SpawnProc)(ThreadHandle,long);
  81.     typedef pascal ThreadHandle (*ScheduleProc)(ThreadHandle);
  82.     typedef pascal Boolean (*ThreadIterProc)(ThreadHandle, void*);
  83.     typedef pascal Boolean         (*ThingIterProc)(ThingHandle, void*);
  84. #endif
  85.  
  86. extern OSErr gThreadError;
  87.  
  88.  
  89.  
  90. typedef long ThreadType;
  91.  
  92. #define    StackCopy            0
  93. /*const ThreadType    HeapStack    =    ;         unimplemented */
  94.  
  95. struct ThreadProcTbl
  96. {
  97.     ThreadProc            fCopyContext;        /* copy current context - store in fStack */
  98.     ThreadProc            fSwapIn;            /* called to context switch "this" thread in */
  99.     ThreadProc            fSwapOut;            /* calls fSchedule then fSwapIn on the nextThread */
  100.     ThreadProc            fFree;                /* called to dispose of the Thread */
  101.     ScheduleProc        fSchedule;            /* queue this thread (if necessary), return the next one */
  102.     ThreadProc            fPreYield;
  103.     ThreadProc            fPostYield;
  104. };
  105.  
  106. typedef struct ThreadProcTbl ThreadProcTbl;
  107.  
  108. typedef long ThreadState;
  109.  
  110. #define    running            0         /* the Thread is the active context */
  111. #define    pending            1        /* the Thread is awaiting scheduleing (ie. on gPendingQueue) */
  112. #define    blocked            2        /* the Thread is on a semaphore */
  113. #define    sleeping        3        /* the Thread is not blocked or pending */
  114. #define    ended            4        /* the Thread is about to be free'd */
  115.  
  116.  
  117. #define kNumberOfUserLongs        8
  118. #define kNumberOfInternalLongs    4
  119.  
  120. struct Thread
  121. {
  122.     struct Thing        fThing;                /* linked list for queue thread is on */
  123.     
  124.     ThreadHandle        fNext;                /* linked list of all threads */
  125.     ThreadHandle        fPrev;
  126.  
  127.     long                fUserBytes[kNumberOfUserLongs];        /* for user use */
  128.  
  129.     void*                fInternalUse;        /* used to keep track of internal globals */
  130.     long                fThreadIdentifier;    /* used for error checking */
  131.     
  132.     ThreadProc             fDream;                /* idle proc that gets called for each thread when LetThreadsDream is called */
  133.     
  134.     /*
  135.     // Do not change the order of any fields above this line.
  136.     // Do not depend on any of the items below this line outside
  137.     // of the threads package.
  138.     */
  139.  
  140.     ThreadProcTbl        fThreadProcs;        /* customizable routines */
  141.     
  142.     ThreadType            fType;
  143.     ThreadState            fState;
  144.     Boolean                fLocked;            /* if the ThreadHandle and fStack are Locked - avoids copious calls to HLock/Hunlock */
  145.     Handle                fStack;                /* the storage for the stack data - if ThreadType == HeapStack this is HLock'ed */
  146.  
  147.     /*
  148.     // Current use of internalBytes:
  149.     //
  150.     //        SleepForNTicks:        0 saves dreamProc, 1 saves sleep len, 2 saves sleep start time
  151.     //
  152.     //        Launcher:            3 saves handle to launch info stuff
  153.     */
  154.     long                fInternalBytes[kNumberOfInternalLongs];        /* for internal use */
  155. };
  156.  
  157. typedef struct Thread Thread;
  158.  
  159. /* manager routines: */
  160.  
  161. pascal OSErr        InitThreads( short threadFlags );
  162. pascal OSErr        ThreadError(void);
  163. pascal ThreadProc    InstallSwapProc( long selector, ThreadProc newSwap );
  164. pascal OSErr        RegisterContextGlobal( long* theGlobal );
  165. pascal OSErr        SetMainThread( ThreadHandle mainThread );
  166. pascal ThreadHandle    GetCurrentThread(void);
  167. pascal ThreadHandle    GetMainThread(void);
  168. pascal void            Yield(void);
  169. pascal void            ExitThreads(void);                            /* while gPendingQueue is not empty Yield */
  170.  
  171. /* thread routines: */
  172.  
  173. pascal ThreadHandle    NewThread(long stackSize /* ThreadType t */);
  174. pascal OSErr        StartThread(ThreadHandle theThread);    /* call fCopy proc and Wake */
  175. pascal Boolean        InThread(ThreadHandle theThread);        /* true if theThread is running */
  176. pascal Boolean        InMainThread(void);                            /* true if mainThread is running */
  177. pascal OSErr        Sleep(ThreadHandle theThread);            /* remove form gPendingQueue (or swap out if running) place on gSleepingQueue */
  178. pascal OSErr        SleepForNTicks(ThreadHandle theThread, long sleepTime);        /* like sleep, but wake up after N ticks */
  179. pascal OSErr        Wake(ThreadHandle theThread);            /* place on gPendingQueue */
  180. pascal OSErr        EndThread(ThreadHandle theThread);        /* call fFree - never returns, end of context */
  181.  
  182. /* convienence routines: */
  183.  
  184. pascal Boolean        InNewThread(ThreadHandle* theThread, long stackSize);    /* NewThread, StartThread, InThread */
  185. pascal ThreadHandle Spawn(ThreadHandle, SpawnProc spawnProc, long stackSize, long refcon);
  186.  
  187.  
  188. /* default methods: */
  189.  
  190. pascal void                TCopyContext(ThreadHandle);    /* copy the current context */
  191. pascal void                TSwapIn(ThreadHandle);        /* make this thread's context the active context */        
  192. pascal void                TSwapOut(ThreadHandle);        /* save the current context (or free the thread if  fState == ended) */
  193. pascal void                TFree(ThreadHandle);        /* dispose of the thread */
  194. pascal ThreadHandle        TSchedule(ThreadHandle);     /* returns the next thread to be run, queue this thread is necessary */
  195.  
  196. /* thing routines */
  197.  
  198. pascal void                IThing(ThingHandle);
  199.  
  200. pascal void                ThingInsertLast(ThingHandle queue, ThingHandle thing);
  201. pascal ThingHandle        ThingTakeFirst(ThingHandle);
  202. pascal ThingHandle        ThingGetFirst(ThingHandle);
  203. pascal void                ThingRemove(ThingHandle thing);
  204.  
  205. pascal ThingHandle        ThingOwner(ThingHandle);                                    /* return the queue this thing is on */
  206. pascal Boolean            ThingIsEmpty(ThingHandle);                                    /* indicate whether or not this thing contains one or more things */
  207.  
  208. pascal void                ThingEach( ThingHandle q, ThingIterProc proc, void* refCon );
  209.  
  210. pascal void                FreeThing(ThingHandle);                                        /* lets go of contained things, but does not free them, then frees self */
  211.  
  212.  
  213. /* dreaming support */
  214.  
  215. pascal void                ThreadEach( ThreadIterProc proc, void* refCon );
  216. pascal void                LetThreadsDream(void);
  217.  
  218. /* semaphores: */
  219.  
  220. struct Semaphore 
  221. {
  222.     struct Thing        fThing;
  223.     long                fCount;
  224.     long                fSemaphoreGID;
  225.     
  226.     SemaphoreHandle        fNext;
  227.     SemaphoreHandle        fPrev;
  228.     
  229.     long                fSemaphoreIdentifier;
  230. };
  231.  
  232. typedef struct Semaphore Semaphore;
  233.  
  234. pascal SemaphoreHandle    NewSemaphore(void);
  235. pascal void                BlockOnSemaphore(SemaphoreHandle, ThreadHandle);
  236. pascal void                ReleaseOneThread(SemaphoreHandle);
  237. pascal void                ReleaseAllThreads(SemaphoreHandle);
  238. pascal void                FreeSemaphore(SemaphoreHandle);
  239.  
  240. pascal void             GrabSemaphore(SemaphoreHandle);
  241. pascal void             ReleaseSemaphore(SemaphoreHandle);
  242.  
  243. pascal SemaphoreHandle    LookupSemaphore( long semaphoreGID );
  244.  
  245.  
  246. #endif